﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RATSharp.Rest;
using RATSharp.Model;
using RATSharp.Collection;
using System.Threading.Tasks;
using RATSharp.Validator;

namespace RATSharp
{
    delegate RATSharp.Model.Object SearchHandler(SearchBy searchBy);
    delegate RATSharp.Model.Object ResultHandler();

    class ObjectBrowser
    {
        private RestService service;

        public ObjectBrowser(RestService service)
        {
            this.service = service;
        }


        public RATSharp.Model.Object init()
        {
            MenuList<MenuItem<string, ResultHandler>, MenuItem<string, ResultHandler>> menuList = new MenuList<MenuItem<string, ResultHandler>, MenuItem<string, ResultHandler>>("How you can find object?");
            menuList.Add(new MenuItem<string, ResultHandler>("Object Search", new ResultHandler(handleObjectSearch)));
            menuList.Add(new MenuItem<string, ResultHandler>("Favourites", new ResultHandler(handleFavouritesSearch)));
            Console.Write(menuList);
            return menuList.ElementAt(MenuUtilities.GetSimpleInput(new IntRangeInputValidator(1, menuList.Count)) - 1).menuHandler();
        }

        private RATSharp.Model.Object handleObjectSearch()
        {
            MenuList<MenuItem<string, SearchHandler>, MenuItem<string, SearchHandler>> menuList = new MenuList<MenuItem<string, SearchHandler>, MenuItem<string, SearchHandler>>("Search by?");
            menuList.Add(new MenuItem<string, SearchHandler>("All", new SearchHandler(handleObjectSearchWithType)));
            menuList.Add(new MenuItem<string, SearchHandler>("Object Name", new SearchHandler(handleObjectSearchWithType)));
            menuList.Add(new MenuItem<string, SearchHandler>("Class Name", new SearchHandler(handleObjectSearchWithType)));
            menuList.Add(new MenuItem<string, SearchHandler>("Object Description", new SearchHandler(handleObjectSearchWithType)));
            menuList.Add(new MenuItem<string, SearchHandler>("Get Back", delegate(SearchBy searchBy) { return null; }));
            Console.Write(menuList);

            int choice = MenuUtilities.GetSimpleInput(new IntRangeInputValidator(1, menuList.Count)) - 1;
            return menuList.ElementAt(choice).menuHandler((SearchBy)choice);
        }

        private RATSharp.Model.Object handleFavouritesSearch()
        {
            Objects foundedObjects;
            if (!MenuUtilities.WaitForCommTask(service.getFavouritesAsync(), out foundedObjects))
            {
                return null;
            }
            if (foundedObjects.Count == 0)
            {
                Console.WriteLine("No favourites has been found.");
                return null;
            }

            MenuList<MenuItem<RATSharp.Model.Object, ResultHandler>, MenuItem<RATSharp.Model.Object, ResultHandler>> menuList = 
                new MenuList<MenuItem<RATSharp.Model.Object, ResultHandler>, MenuItem<RATSharp.Model.Object, ResultHandler>>("Favourites");
            foreach (RATSharp.Model.Object obj in foundedObjects)
            {
                menuList.Add(new MenuItem<RATSharp.Model.Object, ResultHandler>(obj, delegate() { return obj; }));
            }

            Console.Write(menuList);
            int choice = MenuUtilities.GetSimpleInput(new IntRangeInputValidator(1, menuList.Count)) - 1;
            return menuList.ElementAt(choice).menuHandler();
        }



        private RATSharp.Model.Object handleObjectSearchWithType(SearchBy searchBy)
        {
            Console.WriteLine("Find What?");
            string key = MenuUtilities.GetSimpleInput<string>(new StringInputValidator());

            Objects foundedObjects;
            if (!MenuUtilities.WaitForCommTask(service.seachObjects(key, searchBy), out foundedObjects))
            {
                return null;
            }

            if (foundedObjects.Count == 0)
            {
                Console.WriteLine("No results has been found.");
                return null;
            }

            MenuList<MenuItem<RATSharp.Model.Object, ResultHandler>, MenuItem<RATSharp.Model.Object, ResultHandler>> menuList = 
                new MenuList<MenuItem<RATSharp.Model.Object, ResultHandler>, MenuItem<RATSharp.Model.Object, ResultHandler>>("Search results");
            foreach (RATSharp.Model.Object obj in foundedObjects)
            {
                menuList.Add(new MenuItem<RATSharp.Model.Object, ResultHandler>(obj, null));
            }

            Console.Write(menuList);
            int choice = MenuUtilities.GetSimpleInput(new IntRangeInputValidator(1, menuList.Count)) - 1;
            return foundedObjects.ElementAt(choice);
        }

    }
}
